1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing.testers;
18
19 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22 import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
24
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.collect.testing.AbstractMapTester;
27 import com.google.common.collect.testing.features.CollectionSize;
28 import com.google.common.collect.testing.features.MapFeature;
29
30 import java.util.ConcurrentModificationException;
31 import java.util.Iterator;
32 import java.util.Map;
33 import java.util.Map.Entry;
34
35
36
37
38
39
40
41
42
43 @SuppressWarnings("unchecked")
44 @GwtCompatible(emulated = true)
45 public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
46 private Entry<K, V> nullKeyEntry;
47 private Entry<K, V> nullValueEntry;
48 private Entry<K, V> nullKeyValueEntry;
49 private Entry<K, V> presentKeyNullValueEntry;
50
51 @Override public void setUp() throws Exception {
52 super.setUp();
53 nullKeyEntry = entry(null, samples.e3.getValue());
54 nullValueEntry = entry(samples.e3.getKey(), null);
55 nullKeyValueEntry = entry(null, null);
56 presentKeyNullValueEntry = entry(samples.e0.getKey(), null);
57 }
58
59 @MapFeature.Require(SUPPORTS_PUT)
60 public void testPut_supportedNotPresent() {
61 assertNull("put(notPresent, value) should return null", put(samples.e3));
62 expectAdded(samples.e3);
63 }
64
65 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
66 @CollectionSize.Require(absent = ZERO)
67 public void testPutAbsentConcurrentWithEntrySetIteration() {
68 try {
69 Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
70 put(samples.e3);
71 iterator.next();
72 fail("Expected ConcurrentModificationException");
73 } catch (ConcurrentModificationException expected) {
74
75 }
76 }
77
78 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
79 @CollectionSize.Require(absent = ZERO)
80 public void testPutAbsentConcurrentWithKeySetIteration() {
81 try {
82 Iterator<K> iterator = getMap().keySet().iterator();
83 put(samples.e3);
84 iterator.next();
85 fail("Expected ConcurrentModificationException");
86 } catch (ConcurrentModificationException expected) {
87
88 }
89 }
90
91 @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
92 @CollectionSize.Require(absent = ZERO)
93 public void testPutAbsentConcurrentWithValueIteration() {
94 try {
95 Iterator<V> iterator = getMap().values().iterator();
96 put(samples.e3);
97 iterator.next();
98 fail("Expected ConcurrentModificationException");
99 } catch (ConcurrentModificationException expected) {
100
101 }
102 }
103
104 @MapFeature.Require(absent = SUPPORTS_PUT)
105 public void testPut_unsupportedNotPresent() {
106 try {
107 put(samples.e3);
108 fail("put(notPresent, value) should throw");
109 } catch (UnsupportedOperationException expected) {
110 }
111 expectUnchanged();
112 expectMissing(samples.e3);
113 }
114
115 @MapFeature.Require(absent = SUPPORTS_PUT)
116 @CollectionSize.Require(absent = ZERO)
117 public void testPut_unsupportedPresentExistingValue() {
118 try {
119 assertEquals("put(present, existingValue) should return present or throw",
120 samples.e0.getValue(), put(samples.e0));
121 } catch (UnsupportedOperationException tolerated) {
122 }
123 expectUnchanged();
124 }
125
126 @MapFeature.Require(absent = SUPPORTS_PUT)
127 @CollectionSize.Require(absent = ZERO)
128 public void testPut_unsupportedPresentDifferentValue() {
129 try {
130 getMap().put(samples.e0.getKey(), samples.e3.getValue());
131 fail("put(present, differentValue) should throw");
132 } catch (UnsupportedOperationException expected) {
133 }
134 expectUnchanged();
135 }
136
137 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
138 public void testPut_nullKeySupportedNotPresent() {
139 assertNull("put(null, value) should return null", put(nullKeyEntry));
140 expectAdded(nullKeyEntry);
141 }
142
143 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
144 @CollectionSize.Require(absent = ZERO)
145 public void testPut_nullKeySupportedPresent() {
146 Entry<K, V> newEntry = entry(null, samples.e3.getValue());
147 initMapWithNullKey();
148 assertEquals("put(present, value) should return the associated value",
149 getValueForNullKey(), put(newEntry));
150
151 Entry<K, V>[] expected = createArrayWithNullKey();
152 expected[getNullLocation()] = newEntry;
153 expectContents(expected);
154 }
155
156 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS)
157 public void testPut_nullKeyUnsupported() {
158 try {
159 put(nullKeyEntry);
160 fail("put(null, value) should throw");
161 } catch (NullPointerException expected) {
162 }
163 expectUnchanged();
164 expectNullKeyMissingWhenNullKeysUnsupported(
165 "Should not contain null key after unsupported put(null, value)");
166 }
167
168 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
169 public void testPut_nullValueSupported() {
170 assertNull("put(key, null) should return null", put(nullValueEntry));
171 expectAdded(nullValueEntry);
172 }
173
174 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
175 public void testPut_nullValueUnsupported() {
176 try {
177 put(nullValueEntry);
178 fail("put(key, null) should throw");
179 } catch (NullPointerException expected) {
180 }
181 expectUnchanged();
182 expectNullValueMissingWhenNullValuesUnsupported(
183 "Should not contain null value after unsupported put(key, null)");
184 }
185
186 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
187 @CollectionSize.Require(absent = ZERO)
188 public void testPut_replaceWithNullValueSupported() {
189 assertEquals("put(present, null) should return the associated value",
190 samples.e0.getValue(), put(presentKeyNullValueEntry));
191 expectReplacement(presentKeyNullValueEntry);
192 }
193
194 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
195 @CollectionSize.Require(absent = ZERO)
196 public void testPut_replaceWithNullValueUnsupported() {
197 try {
198 put(presentKeyNullValueEntry);
199 fail("put(present, null) should throw");
200 } catch (NullPointerException expected) {
201 }
202 expectUnchanged();
203 expectNullValueMissingWhenNullValuesUnsupported(
204 "Should not contain null after unsupported put(present, null)");
205 }
206
207 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
208 @CollectionSize.Require(absent = ZERO)
209 public void testPut_replaceNullValueWithNullSupported() {
210 initMapWithNullValue();
211 assertNull("put(present, null) should return the associated value (null)",
212 getMap().put(getKeyForNullValue(), null));
213 expectContents(createArrayWithNullValue());
214 }
215
216 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
217 @CollectionSize.Require(absent = ZERO)
218 public void testPut_replaceNullValueWithNonNullSupported() {
219 Entry<K, V> newEntry = entry(getKeyForNullValue(), samples.e3.getValue());
220 initMapWithNullValue();
221 assertNull("put(present, value) should return the associated value (null)",
222 put(newEntry));
223
224 Entry<K, V>[] expected = createArrayWithNullValue();
225 expected[getNullLocation()] = newEntry;
226 expectContents(expected);
227 }
228
229 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
230 public void testPut_nullKeyAndValueSupported() {
231 assertNull("put(null, null) should return null", put(nullKeyValueEntry));
232 expectAdded(nullKeyValueEntry);
233 }
234
235 private V put(Map.Entry<K, V> entry) {
236 return getMap().put(entry.getKey(), entry.getValue());
237 }
238 }
239